package com.atguigu.tingshu.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.common.util.MongoUtil;
import com.atguigu.tingshu.model.user.UserListenProcess;
import com.atguigu.tingshu.user.service.UserListenProcessService;
import com.atguigu.tingshu.vo.album.TrackStatMqVo;
import com.atguigu.tingshu.vo.user.UserListenProcessVo;
import jakarta.annotation.Resource;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@SuppressWarnings({"all"})
public class UserListenProcessServiceImpl implements UserListenProcessService {

	@Autowired
	private MongoTemplate mongoTemplate;

	@Resource
	private RedisTemplate redisTemplate;
    @Autowired
    private RabbitService rabbitService;

	/**
	 * 获取最近一次播放声音
	 * @param userId
	 * @return
	 */
	@Override
	public Map<String, Object> getLatelyTrack(Long userId) {
		Query query = new Query(new Criteria().where("userId").is(userId)).limit(1);
		Sort sort = Sort.by(Sort.Direction.DESC, "updateTime");
		query.with(sort);
		String collectionName = this.getCollectionName(userId);
		List<UserListenProcess> userListenProcessList = mongoTemplate.find(query, UserListenProcess.class, collectionName);
		if (null!=userListenProcessList&& userListenProcessList.size()>0) {
			UserListenProcess userListenProcess = userListenProcessList.get(0);
			// 声明一个map 集合
			Map<String, Object> map = new HashMap<>();
			// 存储数据
			map.put("albumId", userListenProcess.getAlbumId());
			map.put("trackId", userListenProcess.getTrackId());
			return map;
		}
		return null;
	}

	@Override
	public void updateListenProcess(UserListenProcessVo userListenProcessVo, Long userId) {
		String collectionName = this.getCollectionName(userId);
		//1、获取声音，有声音，修改播放进度+更新时间，没有插入
		Query query = new Query(new Criteria().where("trackId").is(userListenProcessVo.getTrackId()));
		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class,collectionName);

		UserListenProcess userLoginProcess =new UserListenProcess();
		if (null !=userListenProcessVo) {
			//不为空，更新声音播放进度+更新使劲
			userLoginProcess.setBreakSecond(userListenProcessVo.getBreakSecond());
			userLoginProcess.setUpdateTime(new Date());
		}else{
			//为空，插入vo
			userLoginProcess=new UserListenProcess();
			//属性copy
			BeanUtils.copyProperties(userListenProcessVo,userLoginProcess);
			userLoginProcess.setUpdateTime(new Date());
			userLoginProcess.setUpdateTime(new Date());
			userLoginProcess.setUserId(userId);
		}
		//2、更新或保存用户播放进度
		mongoTemplate.save(userLoginProcess,collectionName);

		//3、更新声音专辑播放量
		//为防止恶意刷新播放量，一个用户，同一个声音，播放多次，仍然只会执行一次播放量+1

		//防止恶意刷新：redis setnx key value ;
		String key = "track:play:stat:"+userId+":"+userListenProcessVo.getTrackId();
		//判断这个key在缓存中是否存在;---->判断用户是否是当天第一次播放该声音
		Boolean result = redisTemplate.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.DAYS);


		//	判断key是否存在 setbit getbit;
		if (result) {
			//成功，说明第一次播放，mq发消息，专辑微服务监听，更新专辑播放量、声音播放量

			TrackStatMqVo trackStatMqVo = new TrackStatMqVo();
			trackStatMqVo.setAlbumId(userListenProcessVo.getAlbumId());
			trackStatMqVo.setTrackId(userListenProcessVo.getTrackId());
			trackStatMqVo.setCount(1);
			trackStatMqVo.setStatType(SystemConstant.TRACK_STAT_PLAY);
			//	业务编号，防止消息重复消费!
			trackStatMqVo.setBusinessNo(UUID.randomUUID().toString().replace("-",""));
			//发消息
			rabbitService.sendMessage(MqConst.EXCHANGE_TRACK,MqConst.ROUTING_TRACK_STAT_UPDATE, JSON.toJSONString(trackStatMqVo));
		}

	}

	/**
	 * 根据用户ID，声音ID，获取声音播放跳出位置
	 * @param trackId
	 * @param userId
	 * @return
	 */
	@Override
	public BigDecimal getTrackBreakSecond(Long trackId, Long userId) {
		Criteria criteria = new Criteria().where("trackId").is(trackId).and("userId").is(userId);
		Query query=new Query(criteria);
		//获取集合名
		String collectionName = getCollectionName(userId);
		UserListenProcess userListenProcess = mongoTemplate.findOne(query, UserListenProcess.class, collectionName);

		//用户可能没有播放过声音
		if (null!=userListenProcess) {
			//返回声音播放跳出位置
			return userListenProcess.getBreakSecond();
		}

		return new BigDecimal("0");
	}


	/**
	 * 获取集合名
	 * @param userId
	 * @return
	 */
	private String getCollectionName(Long userId) {
		return MongoUtil.getCollectionName(MongoUtil.MongoCollectionEnum.USER_LISTEN_PROCESS, userId);
	}
}
